package cn.zwx.learn.mybatis.example.croe.plugin;

import cn.zwx.learn.mybatis.example.croe.annotation.ZwxIntercepts;
import lombok.AllArgsConstructor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author zhangwenxue
 */

@AllArgsConstructor
public class Plugin implements InvocationHandler {
    private Object target;
    private cn.zwx.learn.mybatis.example.croe.plugin.Interceptor interceptor;

    /**
     * 对被代理对象进行代理，返回代理类
     */
    public static Object wrap(Object obj, cn.zwx.learn.mybatis.example.croe.plugin.Interceptor interceptor) {
        Class clazz = obj.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new Plugin(obj, interceptor));
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 自定义的插件上有@Intercepts注解，指定了拦截的方法
        if (interceptor.getClass().isAnnotationPresent(ZwxIntercepts.class)) {
            // 如果是被拦截的方法，则进入自定义拦截器的逻辑
            if (method.getName().equals(interceptor.getClass().getAnnotation(ZwxIntercepts.class).value())) {
                return interceptor.intercept(new cn.zwx.learn.mybatis.example.croe.plugin.Invocation(target, method, args));
            }
        }
        // 非被拦截方法，执行原逻辑
        return method.invoke(target, method, args);
    }
}
